//
// Created by ZYZ on 2020/6/16.
//
#include <stdio.h>
#include <stdlib.h>
#include "../../src/common/log.h"
#include "../../src/linear_stack/stack_use4_maze.h"
#include "../../include/type_linear_stack.h"

//参考：https://www.cnblogs.com/ABook/p/5424337.html

/*初始化迷宫*/
//其中迷宫中 # 代表墙不通过，空的位置就是通道。
//最后输出的迷宫是解密之后的迷宫，通道里的！代表当前位置不通；* 代表正确的路径。

void InitMaze1(MazeType &maze) {
    maze.arr[0][0] = maze.arr[0][1] = maze.arr[0][2] = maze.arr[0][3] = maze.arr[0][4] = maze.arr[0][5] = maze.arr[0][6] = maze.arr[0][7] = maze.arr[0][8] = maze.arr[0][9] = '#';
    maze.arr[1][0] = maze.arr[1][3] = maze.arr[1][7] = maze.arr[1][9] = '#';
    maze.arr[1][1] = maze.arr[1][2] = maze.arr[1][4] = maze.arr[1][5] = maze.arr[1][6] = maze.arr[1][8] = ' ';
    maze.arr[2][0] = maze.arr[2][3] = maze.arr[2][7] = maze.arr[2][9] = '#';
    maze.arr[2][1] = maze.arr[2][2] = maze.arr[2][4] = maze.arr[2][5] = maze.arr[2][6] = maze.arr[2][8] = ' ';
    maze.arr[3][0] = maze.arr[3][5] = maze.arr[3][6] = maze.arr[3][9] = '#';
    maze.arr[3][1] = maze.arr[3][2] = maze.arr[3][3] = maze.arr[3][4] = maze.arr[3][7] = maze.arr[3][8] = ' ';
    maze.arr[4][0] = maze.arr[4][2] = maze.arr[4][3] = maze.arr[4][4] = maze.arr[4][9] = '#';
    maze.arr[4][1] = maze.arr[4][5] = maze.arr[4][6] = maze.arr[4][7] = maze.arr[4][8] = ' ';
    maze.arr[5][0] = maze.arr[5][4] = maze.arr[5][9] = '#';
    maze.arr[5][1] = maze.arr[5][2] = maze.arr[5][3] = maze.arr[5][5] = maze.arr[5][6] = maze.arr[5][7] = maze.arr[5][8] = ' ';
    maze.arr[6][0] = maze.arr[6][2] = maze.arr[6][6] = maze.arr[6][9] = '#';
    maze.arr[6][1] = maze.arr[6][3] = maze.arr[6][4] = maze.arr[6][5] = maze.arr[6][7] = maze.arr[6][8] = ' ';
    maze.arr[7][0] = maze.arr[7][2] = maze.arr[7][3] = maze.arr[7][4] = maze.arr[7][6] = maze.arr[7][9] = '#';
    maze.arr[7][1] = maze.arr[7][5] = maze.arr[7][7] = maze.arr[7][8] = ' ';
    maze.arr[8][0] = maze.arr[8][1] = maze.arr[8][9] = '#';
    maze.arr[8][2] = maze.arr[8][3] = maze.arr[8][4] = maze.arr[8][5] = maze.arr[8][6] = maze.arr[8][7] = maze.arr[8][8] = ' ';
    maze.arr[9][0] = maze.arr[9][1] = maze.arr[9][2] = maze.arr[9][3] = maze.arr[9][4] = maze.arr[9][5] = maze.arr[9][6] = maze.arr[9][7] = maze.arr[9][8] = maze.arr[9][9] = '#';
}

void InitMaze2(MazeType &maze) {
    maze.arr[0][0] = maze.arr[0][1] = maze.arr[0][2] = maze.arr[0][3] = maze.arr[0][4] = maze.arr[0][5] = maze.arr[0][6] = maze.arr[0][7] = maze.arr[0][8] = maze.arr[0][9] = '#';
    maze.arr[1][0] = maze.arr[1][2] = maze.arr[1][9] = '#';
    maze.arr[1][1] = maze.arr[1][3] = maze.arr[1][4] = maze.arr[1][5] = maze.arr[1][6] = maze.arr[1][7] = maze.arr[1][8] = ' ';
    maze.arr[2][0] = maze.arr[2][2] = maze.arr[2][6] = maze.arr[2][7] = maze.arr[2][8] = maze.arr[2][9] = '#';
    maze.arr[2][1] = maze.arr[2][3] = maze.arr[2][4] = maze.arr[2][5] = ' ';
    maze.arr[3][0] = maze.arr[3][2] = maze.arr[3][6] = maze.arr[3][9] = '#';
    maze.arr[3][1] = maze.arr[3][3] = maze.arr[3][4] = maze.arr[3][5] = maze.arr[3][7] = maze.arr[3][8] = ' ';
    maze.arr[4][0] = maze.arr[4][2] = maze.arr[4][3] = maze.arr[4][4] = maze.arr[4][6] = maze.arr[4][9] = '#';
    maze.arr[4][1] = maze.arr[4][5] = maze.arr[4][7] = maze.arr[4][8] = ' ';
    maze.arr[5][0] = maze.arr[5][4] = maze.arr[5][6] = maze.arr[5][9] = '#';
    maze.arr[5][1] = maze.arr[5][2] = maze.arr[5][3] = maze.arr[5][5] = maze.arr[5][7] = maze.arr[5][8] = ' ';
    maze.arr[6][0] = maze.arr[6][2] = maze.arr[6][4] = maze.arr[6][9] = '#';
    maze.arr[6][1] = maze.arr[6][3] = maze.arr[6][5] = maze.arr[6][6] = maze.arr[6][7] = maze.arr[6][8] = ' ';
    maze.arr[7][0] = maze.arr[7][2] = maze.arr[7][7] = maze.arr[7][8] = maze.arr[7][9] = '#';
    maze.arr[7][1] = maze.arr[7][3] = maze.arr[7][4] = maze.arr[7][5] = maze.arr[7][6] = ' ';
    maze.arr[8][0] = maze.arr[8][2] = maze.arr[8][7] = maze.arr[8][9] = '#';
    maze.arr[8][1] = maze.arr[8][3] = maze.arr[8][4] = maze.arr[8][5] = maze.arr[8][6] = maze.arr[8][8] = ' ';
    maze.arr[9][0] = maze.arr[9][1] = maze.arr[9][2] = maze.arr[9][3] = maze.arr[9][4] = maze.arr[9][5] = maze.arr[9][6] = maze.arr[9][7] = maze.arr[9][8] = maze.arr[9][9] = '#';
}

void InitMaze3(MazeType &maze) {
    maze.arr[0][0] = maze.arr[0][1] = maze.arr[0][2] = maze.arr[0][3] = maze.arr[0][4] = maze.arr[0][5] = maze.arr[0][6] = maze.arr[0][7] = maze.arr[0][8] = maze.arr[0][9] = '#';
    maze.arr[1][0] = maze.arr[1][2] = maze.arr[1][9] = '#';
    maze.arr[1][1] = maze.arr[1][3] = maze.arr[1][4] = maze.arr[1][5] = maze.arr[1][6] = maze.arr[1][7] = maze.arr[1][8] = ' ';
    maze.arr[2][0] = maze.arr[2][2] = maze.arr[2][6] = maze.arr[2][7] = maze.arr[2][8] = maze.arr[2][9] = '#';
    maze.arr[2][1] = maze.arr[2][3] = maze.arr[2][4] = maze.arr[2][5] = ' ';
    maze.arr[3][0] = maze.arr[3][2] = maze.arr[3][6] = maze.arr[3][9] = '#';
    maze.arr[3][1] = maze.arr[3][3] = maze.arr[3][4] = maze.arr[3][5] = maze.arr[3][7] = maze.arr[3][8] = ' ';
    maze.arr[4][0] = maze.arr[4][2] = maze.arr[4][3] = maze.arr[4][4] = maze.arr[4][6] = maze.arr[4][9] = '#';
    maze.arr[4][1] = maze.arr[4][5] = maze.arr[4][7] = maze.arr[4][8] = ' ';
    maze.arr[5][0] = maze.arr[5][4] = maze.arr[5][6] = maze.arr[5][9] = '#';
    maze.arr[5][1] = maze.arr[5][2] = maze.arr[5][3] = maze.arr[5][5] = maze.arr[5][7] = maze.arr[5][8] = ' ';
    maze.arr[6][0] = maze.arr[6][2] = maze.arr[6][4] = maze.arr[6][9] = '#';
    maze.arr[6][1] = maze.arr[6][3] = maze.arr[6][5] = maze.arr[6][6] = maze.arr[6][7] = maze.arr[6][8] = ' ';
    maze.arr[7][0] = maze.arr[7][2] = maze.arr[7][7] = maze.arr[7][9] = '#';
    maze.arr[7][1] = maze.arr[7][3] = maze.arr[7][4] = maze.arr[7][5] = maze.arr[7][6] = maze.arr[7][8] = ' ';
    maze.arr[8][0] = maze.arr[8][2] = maze.arr[8][7] = maze.arr[8][9] = '#';
    maze.arr[8][1] = maze.arr[8][3] = maze.arr[8][4] = maze.arr[8][5] = maze.arr[8][6] = maze.arr[8][8] = ' ';
    maze.arr[9][0] = maze.arr[9][1] = maze.arr[9][2] = maze.arr[9][3] = maze.arr[9][4] = maze.arr[9][5] = maze.arr[9][6] = maze.arr[9][7] = maze.arr[9][8] = maze.arr[9][9] = '#';
}

void print_maze(MazeType maze) {

    char buf[100];
    printf("  ");
    for (int j = 0; j < MAZESIZE; j++) {
        printf("%d ", j);
    }
    printf("\n");

    for (int i = 0; i < MAZESIZE; i++) {
        printf("%d ", i);
        for (int j = 0; j < MAZESIZE; j++) {
            char temp = maze.arr[i][j];
            snprintf(buf, 100, "%c ", temp);      //使用 snprintf() 格式化字符串到 buf 中    //int result = snprintf()
//          printf("result = %d, temp = %s",result,temp);
            if (temp == '#') {
                Log::i(buf);
            } else if (temp == '!') {
                Log::d(buf);
            } else if (temp == '*') {
                Log::w(buf);
            } else {
                Log::i(buf);                                //这里 temp == ''，所以输出空白是为了防止迷宫的墙 # 号挨到一起
            }
        }
        printf("\n");
    }
}

void test_maze() {

#ifdef SELEMTYPE_MAZE

    PosType startPos, endPos;
    startPos.c = startPos.r = 1;
    endPos.c = endPos.r = 8;
    printf("起始点为 (%d,%d), 终止点为 (%d,%d) \n", startPos.c, startPos.r, endPos.c, endPos.r);

//    printf("------ 开始解密 maze1 ------ \n");
//    MazeType maze1;
//    InitMaze1(maze1);
//
//    print_maze(maze1);
//    if (MazePath(maze1, startPos, endPos))
//        printf("迷宫成功解密!\n");
//    else
//        printf("解密失败\n");
//    print_maze(maze1);


    printf("------ 开始解密 maze2 ------ \n");
    MazeType maze2;
    InitMaze2(maze2);

    print_maze(maze2);
    if (MazePath(maze2, startPos, endPos))
        printf("迷宫成功解密!\n");
    else
        printf("解密失败\n");
    print_maze(maze2);

//
//    printf("------ 开始解密 maze3 ------ \n");
//    MazeType maze3;
//    InitMaze3(maze3);
//
//    print_maze(maze3);
//    if (MazePath(maze3, startPos, endPos))
//        printf("迷宫成功解密!\n");
//    else
//        printf("解密失败\n");
//    print_maze(maze3);

#endif
}

//只测试 Maze2
//可见在 (8,3) 从南、西、北 转了一圈依次 pass 不通过后，Stack 进行 Pop 使 (8,4) 在栈顶
//
//获取到新的元素坐标为: (9,4)
//curpos = (9,4)该 curpos 不能 Pass,元素内容为: #
//else 开始 Pop 元素, 该元素当前坐标为 (8,4)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,4)
//获取到新的元素坐标为: (8,3)
//curpos = (8,3)该 curpos 可以 Pass
//Pass, 开始 Push 元素，该元素当前坐标为: (8,3)
//curpos = (8,4)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (8,3)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,3)
//获取到新的元素坐标为: (9,3)
//curpos = (9,3)该 curpos 不能 Pass,元素内容为: #
//else 开始 Pop 元素, 该元素当前坐标为 (8,3)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,3)
//获取到新的元素坐标为: (8,2)
//curpos = (8,2)该 curpos 不能 Pass,元素内容为: #
//else 开始 Pop 元素, 该元素当前坐标为 (8,3)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,3)
//获取到新的元素坐标为: (7,3)
//curpos = (7,3)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (8,3)
//
//direction == 4，开始 Pop 元素, 该元素当前坐标为 (8,3)
//direction == 4, Pop 完获取到的栈顶元素坐标为 (8,4)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,4)
//获取到新的元素坐标为: (7,4)
//curpos = (7,4)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (8,4)
//
//direction == 4，开始 Pop 元素, 该元素当前坐标为 (8,4)
//direction == 4, Pop 完获取到的栈顶元素坐标为 (8,5)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,5)
//获取到新的元素坐标为: (7,5)
//curpos = (7,5)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (8,5)
//direction == 4，开始 Pop 元素, 该元素当前坐标为 (8,5)
//direction == 4, Pop 完获取到的栈顶元素坐标为 (8,6)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (8,6)
//获取到新的元素坐标为: (7,6)
//curpos = (7,6)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (8,6)
//direction == 4，开始 Pop 元素, 该元素当前坐标为 (8,6)
//direction == 4, Pop 完获取到的栈顶元素坐标为 (7,6)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (7,6)
//获取到新的元素坐标为: (7,5)
//curpos = (7,5)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (7,6)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (7,6)
//
//获取到新的元素坐标为: (6,6)
//curpos = (6,6)该 curpos 可以 Pass
//Pass, 开始 Push 元素，该元素当前坐标为: (6,6)
//curpos = (6,7)该 curpos 可以 Pass
//Pass, 开始 Push 元素，该元素当前坐标为: (6,7)
//curpos = (6,8)该 curpos 可以 Pass
//Pass, 开始 Push 元素，该元素当前坐标为: (6,8)
//curpos = (6,9)该 curpos 不能 Pass,元素内容为: #
//else 开始 Pop 元素, 该元素当前坐标为 (6,8)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (6,8)
//
//获取到新的元素坐标为: (7,8)
//curpos = (7,8)该 curpos 不能 Pass,元素内容为: #
//else 开始 Pop 元素, 该元素当前坐标为 (6,8)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (6,8)
//获取到新的元素坐标为: (6,7)
//curpos = (6,7)该 curpos 不能 Pass,元素内容为: *
//else 开始 Pop 元素, 该元素当前坐标为 (6,8)
//开始向下一个方向探索, 开始 Push 元素，该元素当前坐标为: (6,8)
//
//...
//解密失败